package config

import (
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

type Setting struct {
	vp *viper.Viper
}

//var sections = make(map[string]interface{})

//func (s *Setting) ReadSection(k string, v interface{}) error {
//	err := s.vp.UnmarshalKey(k, v)
//	if err != nil {
//		return err
//	}
//	if _, ok := sections[k]; !ok {
//		sections[k] = v
//	}
//
//	return nil
//}

func (s *Setting) reloadAllSection(configs *Configs) error {
	//for k, v := range sections {
	//	err := s.ReadSection(k, v)
	//	if err != nil {
	//		return err
	//	}
	//}

	if err := s.vp.Unmarshal(configs); err != nil {
		return err
	}

	return nil
}

func (s *Setting) watchSettingChange(configs *Configs) {
	go func() {
		s.vp.WatchConfig()
		s.vp.OnConfigChange(func(in fsnotify.Event) {
			_ = s.reloadAllSection(configs)
		})
	}()
}

func NewSetting(configFile string) (*Configs, error) {
	vp := viper.New()
	vp.SetConfigType("yaml")

	if configFile != "" {
		vp.SetConfigFile(configFile)
	} else {
		vp.AddConfigPath("config/")
		vp.SetConfigName("prod")
	}

	if err := vp.ReadInConfig(); err != nil {
		return nil, err
	}

	s := &Setting{
		vp,
	}

	configs := &Configs{}
	// 设置默认值
	configs.SetDefaults()
	err := s.reloadAllSection(configs)
	if err != nil {
		return nil, err
	}

	s.watchSettingChange(configs)

	return configs, nil
}
